#include "uart.h"
#include "board.h"
//uartStruct_t devUART1;
//static uint8_t buffer[UART1_BUF_SIZE] = {0};
//static uint8_t *pbuffer = NULL;
//static uint16_t recvLength = 0;

//static void UART1_SendBytes(uint8_t *pBuf, uint32_t length);
//static void UART1_PrintString(const char *fmt, ...);
//static uint16_t UART1_ReadBytes(uint8_t *pBuf);
void USART1_Init(uint32_t BaudRate) {
	LL_RCC_ClocksTypeDef rcc_clocks;
	/* (1) Enable GPIO clock and configures the USART pins **********************/

	/* Enable the peripheral clock of GPIO Port */
	LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
	/* Configure Tx Pin as : Alternate function, High Speed, Push pull, Pull up */
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_9, LL_GPIO_MODE_ALTERNATE);
	LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_9, LL_GPIO_SPEED_FREQ_HIGH);
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_9, LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_9, LL_GPIO_PULL_UP);
	LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_9, LL_GPIO_AF_7);

	/* Configure Rx Pin as : Alternate function, High Speed, Push pull, Pull up */
	LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_10, LL_GPIO_MODE_ALTERNATE);
	LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_10, LL_GPIO_SPEED_FREQ_HIGH);
	LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_10, LL_GPIO_OUTPUT_PUSHPULL);
	LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_10, LL_GPIO_PULL_UP);
	LL_GPIO_SetAFPin_8_15(GPIOA, LL_GPIO_PIN_10, LL_GPIO_AF_7);

	/* (2) Enable USART1 peripheral clock and clock source ****************/
	LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
	

	/* (3) Configure USART1 functional parameters ********************************/

	/* TX/RX direction */
	LL_USART_SetTransferDirection(USART1, LL_USART_DIRECTION_TX_RX);
	/* 8 data bit, 1 start bit, 1 stop bit, no parity */
	LL_USART_ConfigCharacter(USART1, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1);
	LL_USART_SetOverSampling(USART1, LL_USART_OVERSAMPLING_16);
	LL_USART_SetHWFlowCtrl(USART1, LL_USART_HWCONTROL_NONE);
	LL_RCC_GetSystemClocksFreq(&rcc_clocks);
	LL_USART_SetBaudRate(USART1, rcc_clocks.PCLK2_Frequency, LL_USART_OVERSAMPLING_16, BaudRate); 
	
//	NVIC_SetPriority(USART1_IRQn, 2);  
//	NVIC_EnableIRQ(USART1_IRQn);
//	LL_USART_EnableIT_IDLE(USART1);
//	LL_USART_EnableIT_RXNE(USART1);
	/* (4) Enable USART1 **********************************************************/
	LL_USART_ConfigAsyncMode(USART1);
	LL_USART_Enable(USART1);
//	recvLength = 0;
//	memset(buffer, 0, sizeof(buffer));
//	pbuffer = buffer;
//	devUART1.recvFlag = false;
//	devUART1.write = UART1_SendBytes;
//	devUART1.read = UART1_ReadBytes;
//	devUART1.print = UART1_PrintString;
}

//static void UART1_SendBytes(uint8_t *pBuf, uint32_t length) {
//	uint32_t i;
//	for(i=0;i<length;i++) {
//		LL_USART_TransmitData8(USART1, pBuf[i]);
//		while(LL_USART_IsActiveFlag_TXE(USART1) == RESET);
//	}
//}

//static void UART1_PrintString(const char *fmt, ...) {
//	uint16_t i;
//	va_list argptr;
//	va_start(argptr, fmt);
//	memset(uartShareBuffer, 0, sizeof(uartShareBuffer));
//	vsprintf((char*)uartShareBuffer, fmt, argptr);
//	va_end(argptr);
//	for(i=0;i<strlen((char*)uartShareBuffer);i++) {
//		if(uartShareBuffer[i] == '\n') {
//			LL_USART_TransmitData8(USART1, '\r');
//			while(LL_USART_IsActiveFlag_TXE(USART1) == RESET);
//		}
//		LL_USART_TransmitData8(USART1, uartShareBuffer[i]);
//		while(LL_USART_IsActiveFlag_TXE(USART1) == RESET);
//	}
//}

//static uint16_t UART1_ReadBytes(uint8_t *pBuf) {
//	memcpy(pBuf, buffer, recvLength);
//	devUART1.recvFlag = false;
//	return recvLength;
//}

//static void UART1_Receive_Callback(void) {
//	*pbuffer++ = LL_USART_ReceiveData8(USART1);
//}

//static void UART1_Idle_Callback(void) {
//	recvLength = pbuffer - buffer;
//	pbuffer = buffer;
//	devUART1.recvFlag = true;
//	printf("%3d\n", LL_USART_ReceiveData8(USART1));
//}

void USART1_IRQHandler(void) {
//	if(LL_USART_IsActiveFlag_RXNE(USART1)) {
//		LL_USART_ClearFlag_RXNE(USART1);
//		UART1_Receive_Callback();
//	}
//	else 
//	if(LL_USART_IsActiveFlag_IDLE(USART1)) {
//		LL_USART_ClearFlag_IDLE(USART1);
//		UART1_Idle_Callback();
//	}
}

int fputc(int ch, FILE *f) {
	if(((char)ch == '\n')) {
		LL_USART_TransmitData8(USART1, '\r');
		while(LL_USART_IsActiveFlag_TXE(USART1) == RESET);
	}
	LL_USART_TransmitData8(USART1, (char)ch);
	while(LL_USART_IsActiveFlag_TXE(USART1) == RESET);
	return ch;
}

int getc(FILE *f) {
	while(LL_USART_IsActiveFlag_RXNE(USART1)==RESET);
	return (int)LL_USART_ReceiveData8(USART1);
}
